package dao

import (
	"context"
	"database/sql"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

var (
	ErrUserDuplicateEmail = errors.New("邮箱冲突")
	ErrUserNotFound       = errors.New("用户不存在")
)

type User struct {
	Id       int64  `gorm:"primaryKey,autoIncrement"`
	Email    string `gorm:"unique"`
	Password string
	Birthday sql.NullTime
	Profile  string
	Nickname string
	Ctime    int64
	Utime    int64
}

type UserDao struct {
	db *gorm.DB
}

func (dao *UserDao) FindByEmail(c context.Context, email string) (User, error) {
	var u User
	err := dao.db.WithContext(c).Where("email=?", email).First(&u).Error
	return u, err
}

func NewUserDao(db *gorm.DB) *UserDao {
	return &UserDao{
		db: db,
	}
}

func (dao *UserDao) Insert(ctx context.Context, u User) error {
	// 存毫秒数
	now := time.Now().UnixMilli()
	u.Utime = now
	u.Ctime = now
	err := dao.db.WithContext(ctx).Create(&u).Error
	if mysqlErr, ok := err.(*mysql.MySQLError); ok {
		const uniqueConflictsErrNo uint16 = 1062
		if mysqlErr.Number == uniqueConflictsErrNo {
			return ErrUserDuplicateEmail
		}
	}
	return err
}

func (dao *UserDao) GetUserProfileById(ctx context.Context, id int64) (User, error) {

	var u User
	err := dao.db.WithContext(ctx).Where("id=?", id).First(&u).Error
	if err != nil {
		return User{}, err
	}
	return u, nil

}

func (dao *UserDao) UpdateUser(c *gin.Context, user User) error {
	var u User
	err := dao.db.WithContext(c).Where("id=?", user.Id).First(&u).Error
	if err != nil {
		return err
	}
	if user.Email != "" {
		u.Email = user.Email
	}
	if user.Nickname != "" {
		u.Nickname = user.Nickname
	}
	if user.Profile != "" {
		u.Profile = user.Profile
	}
	if user.Birthday.Valid {
		u.Birthday = user.Birthday
	}
	return dao.db.WithContext(c).Save(&u).Error
}
